package com.caocaog.market.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caocaog.market.entity.*;
import com.caocaog.market.mapper.ShopBasicMapper;
import com.caocaog.market.merchant.entity.MkMerchantBasic;
import com.caocaog.market.merchant.service.MkMerchantService;
import com.caocaog.market.service.IShopBasicService;
import com.caocaog.market.service.IShopChannelService;
import com.caocaog.market.service.IShopChannelshopService;
import com.caocaog.market.util.DistanceUtil;
import com.caocaog.market.vo.GoodsInfoVo;
import com.caocaog.market.vo.ShopVo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;

/**
 * 店铺信息表
 *
 * @author jeecg-boot
 * @date 2021-11-19
 */
@Service
@Transactional
@RequiredArgsConstructor
public class ShopBasicServiceImpl extends ServiceImpl<ShopBasicMapper, ShopBasic> implements IShopBasicService {

    @Autowired
    private IShopChannelService shopChannelService;

    @Autowired
    private IShopChannelshopService shopChannelshopService;


    @Override
    public List<AreaProvince> selectAreaProvinceList() {
        return this.baseMapper.selectAreaProvinceList();
    }

    @Override
    public List<AreaCity> selectAreaCityList(Integer id) {
        return this.baseMapper.selectAreaCityList(id);
    }

    @Override
    public List<AreaDistrict> selectAreaDistrictList(Integer id) {
        return this.baseMapper.selectAreaDistrictList(id);
    }

    @Override
    public AreaDistrict selectAreaDistrictOne(Integer id) {

        return this.baseMapper.selectAreaDistrictOne(id);
    }

    @Override
    public ShopBasic selectOneByUserForServe() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        this.checkShopBasicByLoginUser(loginUser);
        return super.baseMapper.selectOne(new LambdaQueryWrapper<ShopBasic>()
                .eq(ShopBasic::getMerchantId, loginUser.getMerchantId())
                .last("limit 1")
        );
    }

    @Override
    public String addForServe(ShopBasic shopBasic) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        this.checkShopBasicByLoginUser(loginUser);
        shopBasic.setMerchantId(loginUser.getMerchantId());
        super.baseMapper.insert(shopBasic);
        return shopBasic.getId();
    }

    @Override
    public List<GoodsInfoVo> selectGoodsVoByShopId(String id) {
        return super.baseMapper.selectGoodsVoByShopId(id);
    }

    @Override
    public List<ShopVo> selectShopListAndTakeOutInfoByRecommend(ShopBasic shopBasic) {
        return super.baseMapper.selectShopListAndTakeOutInfoByRecommendForSDX(shopBasic);
    }

    @Override
    public Result<?> shopListByChannelId(String siteId, String channelId, String lat, String lng) {
        ShopChannel shopChannel = shopChannelService.getById(channelId);
        if (shopChannel == null) {
            return Result.error("暂无此频道信息数据，channelId-> " + channelId, 404);
        }
        List<ShopVo> shopVoList;
        List<ShopVo> resultList = new ArrayList<>();
        List<String> shopIds;
        // 如果是一级，就获取所有二级频道ids
        if (shopChannel.getParentId().equals("0")) {
            List<String> shopChannelIds = shopChannelService.queryTreeListByPid(channelId)
                    .stream().map(ShopChannel::getId).collect(Collectors.toList());
            shopChannelIds.add(shopChannel.getId());
            shopIds = shopChannelshopService.getShopIdsByChannelIdSiteId(
                    StringUtils.join(shopChannelIds, ","), siteId);
        } else {
            shopIds = shopChannelshopService.getShopIdsByChannelIdSiteId(channelId, siteId);
        }
        if (oConvertUtils.listIsNotEmpty(shopIds)) {
            shopVoList = super.baseMapper.selectShopListAndTakeOutInfo(shopIds, null);
            //店铺名 logo 评分  四个商品 名x
            for (ShopVo shopVo : shopVoList) {
                List<GoodsInfoVo> voList = super.baseMapper.selectGoodsVoByShopId(shopVo.getId());
                shopVo.setGoodsVoList(voList);
                //计算每个店铺的距离
                if (oConvertUtils.isNotEmpty(shopVo.getLat()) && oConvertUtils.isNotEmpty(shopVo.getLng())) {
                    double distance = DistanceUtil.getDistanceMeter(Double.parseDouble(lat), Double.parseDouble(lng),
                            Double.parseDouble(shopVo.getLat()), Double.parseDouble(shopVo.getLng()));
                    shopVo.setDistance(distance);
                }
            }
            //根据 距离排序
            shopVoList.sort(comparing(ShopVo::getDistance));
            // 如果没有siteId 则超出 30km 就不显示了
            if (StringUtils.isBlank(siteId)) {
                List<ShopVo> finalResultList = resultList;
                shopVoList.forEach(shopBasic -> {
                    if (shopBasic.getDistance() >= 30) {
                        return;
                    }
                    finalResultList.add(shopBasic);
                });
            } else {
                resultList = shopVoList;
            }

        }

        resultList.forEach(s -> System.out.println(s.getName() + " " + s.getDistance()));
        return Result.OK(resultList);
    }

    @Override
    public Result shopListByChannelIdForSDX(String channelId, String lat, String lng) {
        ShopChannel shopChannel = shopChannelService.getById(channelId);
        Map map = new HashMap();
        List<ShopVo> shopVoList = new ArrayList<>();
        List<ShopChannel> shopChannelList = new ArrayList<>();
        List<String> shopIds = new ArrayList<>();
        if (shopChannel.getParentId().equals("0")) {
            //获取一级下的所有频道 二级频道-全部和一级频道一致
            shopChannelList = shopChannelService.queryTreeListByPid(channelId);
            List<String> shopChannels = shopChannelList.stream().map(ShopChannel::getId).collect(Collectors.toList());
            if (oConvertUtils.listIsNotEmpty(shopChannels)) {
                shopIds = shopChannelshopService.list(new QueryWrapper<ShopChannelshop>()
                                .select("distinct shop_id")
                                .in("channel_id", shopChannels))
                        .stream().map(ShopChannelshop::getShopId).collect(Collectors.toList());
            }
            map.put("shopChannelList", shopChannelList);
        } else if (shopChannel.getName().equals("全部")) {
            //获取父级下的所有频道 二级频道-全部和一级频道一致
            shopChannelList = shopChannelService.queryTreeListByPid(shopChannel.getParentId());
            List<String> shopChannels = shopChannelList.stream().map(ShopChannel::getId).collect(Collectors.toList());
            if (oConvertUtils.listIsNotEmpty(shopChannels)) {
                shopIds = shopChannelshopService.list(new QueryWrapper<ShopChannelshop>().in("channel_id", shopChannels))
                        .stream().map(ShopChannelshop::getShopId).collect(Collectors.toList());
            }
            map.put("shopChannelList", shopChannelList);
        } else {
            //二级频道
            shopIds = shopChannelshopService.list(new QueryWrapper<ShopChannelshop>().eq("channel_id", channelId))
                    .stream().map(ShopChannelshop::getShopId).collect(Collectors.toList());
        }
        if (oConvertUtils.listIsNotEmpty(shopIds)) {
            shopVoList = super.baseMapper.selectShopListAndTakeOutInfo(shopIds, null);
            //店铺名 logo 评分  四个商品 名
            for (ShopVo shopVo : shopVoList) {
                List<GoodsInfoVo> voList = super.baseMapper.selectGoodsVoByShopId(shopVo.getId());
                shopVo.setGoodsVoList(voList);
                //计算每个店铺的距离
                if (oConvertUtils.isNotEmpty(shopVo.getLat()) && oConvertUtils.isNotEmpty(shopVo.getLng())) {
                    Double distance = DistanceUtil.getDistanceMeter(Double.parseDouble(lat), Double.parseDouble(lng),
                            Double.parseDouble(shopVo.getLat()), Double.parseDouble(shopVo.getLng()));
                    shopVo.setDistance(distance);
                }

            }

            //根据 距离排序
            shopVoList.sort(comparing(ShopVo::getDistance));
        }

        map.put("shopVoList", shopVoList);
        shopVoList.forEach(s -> {
            System.out.println(s.getName() + " " + s.getDistance());
        });
        return Result.OK(map);
    }

    @Override
    public List<ShopVo> selectShopListAndTakeOutInfo(List<String> ids, Integer recommend) {
        return super.baseMapper.selectShopListAndTakeOutInfo(ids, recommend);
    }

    @Override
    public List<ShopVo> selectShopListAndTakeOutInfoByRecommend(String siteId, ShopBasic shopBasic) {
        List<ShopVo> shopVos = super.baseMapper.selectShopListAndTakeOutInfoByRecommend(siteId, shopBasic);
        if (shopVos.isEmpty()) return shopVos;

        LocalDateTime now = LocalDateTime.now();
        shopVos.forEach(shopVo -> shopVo.setInBusiness(now));
        shopVos.sort(comparing(item -> !item.isInBusiness()));
        return shopVos;
    }

    @Autowired
    public MkMerchantService merchantService;

    @Override
    public List<ShopVo> getSurroundingServeShop(String lat, String lng, String siteId) {
        List<String> merchantIds = merchantService.findMerchantBySiteId(siteId)
                .stream().filter(item -> StringUtils.isNotBlank(item.getType()) && item.getType().contains("2"))
                .map(MkMerchantBasic::getId).collect(Collectors.toList());
        if (merchantIds.isEmpty()) return Collections.emptyList();

        // 获取所有服务类型的店铺（ type = 2 ）已经siteId分站下的店铺
        List<ShopBasic> shopBasics = super.baseMapper.selectList(new LambdaQueryWrapper<ShopBasic>()
                .eq(ShopBasic::getType, 2)
                .in(ShopBasic::getMerchantId, merchantIds)
        );
        if (shopBasics.isEmpty()) return Collections.emptyList();

        List<ShopVo> shopVoList = super.baseMapper.selectServeShopListAndTakeOutInfo(
                shopBasics.stream().map(ShopBasic::getId).collect(Collectors.toList()), null);
        //计算每个店铺的距离
        return shopVoList.stream().peek(vo -> {
            Double distance = DistanceUtil.getDistanceMeter(Double.parseDouble(lat), Double.parseDouble(lng),
                    Double.parseDouble(vo.getLat()), Double.parseDouble(vo.getLng()));
            vo.setDistance(Double.parseDouble(String.format("%.2f", distance)));
        }).sorted(comparing(ShopVo::getDistance)).collect(Collectors.toList());
    }

    @Override
    public ShopBasic getShopInfo(String shopId, String lat, String lng) {
        ShopBasic shopBasic = super.baseMapper.selectById(shopId);
        Double distance = DistanceUtil.getDistanceMeter(Double.parseDouble(lat), Double.parseDouble(lng),
                Double.parseDouble(shopBasic.getLat()), Double.parseDouble(shopBasic.getLng()));
        shopBasic.setDistance(Double.parseDouble(String.format("%.2f", distance)));
        return shopBasic;
    }

    @Override
    public List<String> getShopIdsByMerchantIds(List<String> merchantIds) {
        return super.baseMapper.selectList(new LambdaQueryWrapper<ShopBasic>()
                        .in(ShopBasic::getMerchantId, merchantIds))
                .stream().map(ShopBasic::getId).collect(Collectors.toList());
    }

    @Override
    public List<ShopBasic> getShopByMerchantId(String merchantId) {
        return baseMapper.selectList(new LambdaQueryWrapper<ShopBasic>()
                .eq(ShopBasic::getMerchantId,merchantId));
    }

    /**
     * 根据商家id获取店铺集合，正在营业的
     *
     * @param merchantId 商家id
     * @return 店铺集合
     */
    @Override
    public List<ShopBasic> getOpenShopByMerchantId(String merchantId) {
        return baseMapper.selectList(new LambdaQueryWrapper<ShopBasic>()
                .eq(ShopBasic::getMerchantId,merchantId)
                .eq(ShopBasic::getIsRest,0))
                ;
    }

    private void checkShopBasicByLoginUser(LoginUser loginUser) {
        if (loginUser.getUserType() != 3) {
            throw new JeecgBootException("用户需为商家类型, realName-> " + loginUser.getRealname());
        }
        if (StringUtils.isBlank(loginUser.getMerchantId())) {
            throw new JeecgBootException("用户暂未绑定商家, realName-> " + loginUser.getRealname());
        }
    }
}
